﻿
Partial Class Public_Login
    Inherits System.Web.UI.Page

    Public Sub InitData()
        Me.Page.Form.DefaultButton = Me.btnLogin.ID
    End Sub

    '依據請求執行 (例如 GridView.Editing)
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim wf As WebForm_ManageImpersonation = TryCast(Context.Handler, WebForm_ManageImpersonation)

        If wf IsNot Nothing Then
            Me.PostLoginProcessing(wf.UserID)
        End If

        If Not IsPostBack Then

            ' SSO
            If Request.ServerVariables("HTTP_X_cn") <> "" Then
                Dim userID As String = Request.ServerVariables("HTTP_X_cn")
                Me.UserID = userID

                If Me.SSOAutoLogin(userID) = True Then
                    Me.PostLoginProcessing(userID)
                    Return
                End If
            End If

            Me.UpdatePublicAuth()
        End If

    End Sub

#Region "方法"
    Public Function Login() As Boolean
        Dim dat As New clsData
        Dim dt As Data.DataTable
        Dim sql As New MyStringBuilder

        Dim loginResult As Boolean
        Dim userID As String = ""

        sql.Length = 0
        sql.AppendFormat("select e.* ")
        sql.AppendFormat("from Employee e ")
        sql.AppendFormat("where e.WindowsID = '{0}' or e.EmployeeID = '{0}' ", Me.txtUserID.Text.Replace("'", "''"))

        dt = dat.GetData(sql)

        '判斷是否為機關人員
        If dt.Rows.Count > 0 Then

            '非公務帳號或測試環境需比對密碼
            If (TypeOf dt.Rows(0)("WindowsID") Is DBNull Or dt.Rows(0)("WindowsID").ToString() = "") Then

                If TypeOf dt.Rows(0)("Password") Is DBNull Then
                    dt.Rows(0)("Password") = clsAuth.EncryptPassword("")
                End If

                ' MD5密碼比對
                If clsAuth.EncryptPassword(Me.txtPassword.Text) = dt.Rows(0)("Password") Then
                    loginResult = True
                    userID = dt.Rows(0)("EmployeeID")

                    GoTo Login_Success
                Else
                    MyObj.ShowMessage("Invalid Password!!")
                    Return False
                End If
            Else
                '公務帳號從 SSO 登入
                Me.Response.Redirect(clsAuth.GetSSOUrl())
            End If
        Else
            MyObj.ShowMessage("Invalid Username!!")
            Return False
        End If

Login_Success:
        If loginResult = True Then
            Me.WriteLoginRecord(True)
            Me.PostLoginProcessing(userID)
        Else
            MyObj.ShowMessage("Invalid Username!!")
            Return False
        End If
    End Function

    ''' <summary>
    ''' 登入成功後之處理
    ''' </summary>
    ''' <param name="userID"></param>
    ''' <remarks></remarks>
    ''' 
    Public Sub PostLoginProcessing(ByVal userID As String)
        Me.BindData(userID)
        FormsAuthentication.SetAuthCookie(userID, False)

        '依據此組織資料，判斷表單裡每筆資料之權限
        '登出後清空此資料以節省空間

        '單位權限已停用
        'clsAuth.BuildOrganizationAuth(userID)

        '依據此表單權限資料，判斷登入者對表單之權限
        '登出後清空此資料以節省空間
        'clsAuth.BuildProgramAuth(userID)

        If FormsAuthentication.GetRedirectUrl(userID, False) <> "" Then
            '登入預設首頁,避免ID切換但無原頁面權限
            Me.Response.Redirect(clsAuth.GetDefaultUrl())
            'FormsAuthentication.RedirectFromLoginPage(userID, False)
        Else
            Me.Response.Redirect(clsAuth.GetDefaultUrl())
        End If
    End Sub

    Public Sub BindData(ByVal userID As String)
        Me.Request.Cookies.Clear()
        Me.Response.Cookies.Clear()

        Dim dt As Data.DataTable
        Dim dat As New clsData
        Dim sql As New MyStringBuilder
        Dim builder As SelectStringBuilder

        '取得個人資訊
        builder = New SelectStringBuilder(MyDataView.User, "u")
        builder.AddColumn("u.*")
        builder.AddVarCondition("u.UserID", "UserID")
        builder.AddWithValue("UserID", userID)
        dt = dat.GetData(builder)

        Dim UserName As String = HttpUtility.UrlEncode(dt.Rows(0)("UserName").ToString())
        Session("UserID") = userID
        clsCookie.CookieSet("UserName", UserName)

        'me.Response.Cookies("UserID").Value = HttpUtility.UrlEncode(dt.Rows(0)("UserID").ToString())        
        clsCookie.CookieSet("UserTypeValue", dt.Rows(0)("UserType"))

        Dim dtInternalUser As Data.DataTable

        '若屬於運用單位人員, 傳回單位資訊
        builder = New SelectStringBuilder(MyDataView.InternalUser, "u")
        builder.AddColumn("u.*")
        builder.AddColumn("o.OrganizationName, o.OrganizationID")
        builder.InnerJoin(MyDataView.OrganizationView, "o", "u.UOrganizationID", "o.UOrganizationID")
        builder.AddVarCondition("u.UserID", "UserID")
        builder.AddWithValue("UserID", userID)
        dtInternalUser = dat.GetData(builder)

        clsCookie.CookieSet("UOrganizationID", dtInternalUser.Rows(0)("UOrganizationID"))
        clsCookie.CookieSet("UOrganizationID", dtInternalUser.Rows(0)("OrganizationID"))
        clsCookie.CookieSet("OrganizationName", HttpUtility.UrlEncode(dtInternalUser.Rows(0)("OrganizationName")))

        '取得職務列表
        builder = New SelectStringBuilder(MyDataView.RoleUserMappingView, "ru")
        builder.AddColumn("ru.*")
        builder.AddVarCondition("ru.UserID", "UserID")

        builder.AddWithValue("UserID", userID)

        dt = dat.GetData(builder)

        Dim roleList As New List(Of String)
        For Each dr As Data.DataRow In dt.Rows
            roleList.Add(dr("RoleID"))
        Next

        If roleList.Count = 0 Then
            'roleList.Add("0")
        End If

        roleList.Add(clsAuth.GetRoleIDByName("Everyone"))

        clsCookie.CookieSet("RoleList", String.Join(",", roleList.ToArray()))

        Using scope As New Transactions.TransactionScope
            sql.Length = 0
            sql.AppendFormat("delete from UserRoleAuth ")
            sql.AppendFormat("where UserID = '{0}' ", userID.Replace("'", "''"))
            dat.AccData(sql)

            For Each roleID As String In roleList
                sql.Length = 0
                sql.AppendFormat("insert UserRoleAuth (UserID, RoleID) ")
                sql.AppendFormat("select '{0}' ", userID.Replace("'", "''"))
                sql.AppendFormat(", '{0}' ", roleID)
                sql.AppendFormat("where not exists(select * from UserRoleAuth where UserID='{0}' and RoleID='{1}') ", userID.Replace("'", "''"), roleID)
                dat.AccData(sql)
            Next
            scope.Complete()
        End Using

        'Me.Response.Cookies("UserType").Expires = Now.AddMonths(1)
        clsCookie.CookieSet("UserType", "")

    End Sub

    '人員登入紀錄
    Private Sub WriteLoginRecord(ByVal success As Boolean)
        Dim dat As New clsData
        Dim sql As New MyStringBuilder

        Using scope As New Transactions.TransactionScope
            sql.Length = 0
            sql.AppendFormat("insert LoginRecord(EmployeeID, LoginDate, Success) select ")
            sql.AppendFormat(" UserID = '{0}' ", Me.UserID.Replace("'", "''"))
            sql.AppendFormat(",LoginDate = getdate() ")
            sql.AppendFormat(",Success = '{0}' ", IIf(success = True, "Y", "N"))
            dat.AccData(sql)

            scope.Complete()
        End Using
    End Sub

    Public Function SSOAutoLogin(ByVal userID As String) As Boolean
        Dim dat As New clsData
        Dim sql As New MyStringBuilder

        sql.Length = 0
        sql.AppendFormat("select e.* ")
        sql.AppendFormat("from Employee e ")
        sql.AppendFormat("where e.WindowsID = '{0}' or e.EmployeeID = '{0}' ", userID.Replace("'", "''"))

        If dat.GetData(sql).Rows.Count > 0 Then
            Return True
        Else
            MyObj.ShowMessage("Invalid Username!")
            Return False
        End If
    End Function

    Public Sub UpdatePublicAuth()
        Dim userID As String = ""
        Dim dat As New clsData
        Dim sql As New MyStringBuilder
        Dim roleList As New List(Of String)

        roleList.Add(clsAuth.GetRoleIDByName("Everyone"))

        Using scope As New Transactions.TransactionScope
            sql.Length = 0
            sql.AppendFormat("delete from UserRoleAuth ")
            sql.AppendFormat("where UserID = '{0}' ", userID.Replace("'", "''"))
            dat.AccData(sql)

            For Each roleID As String In roleList
                sql.Length = 0
                sql.AppendFormat("insert UserRoleAuth (UserID, RoleID) ")
                sql.AppendFormat("select '{0}' ", userID.Replace("'", "''"))
                sql.AppendFormat(", '{0}' ", roleID)

                dat.AccData(sql)
            Next
            scope.Complete()
        End Using
    End Sub

    Public Sub CheckMaintain()
        If Me.UserID.ToLower().Trim() <> "angus" AndAlso Me.UserID.ToLower().Trim() <> "administrator" Then
            Dim dat As New clsData
            Dim sql As New MyStringBuilder
            Dim dt As DataTable

            sql.Length = 0
            sql.AppendFormat("select * from SystemParameter where ParameterType='System' and ParameterName='Maintain' and Active='Y' ")
            dt = dat.GetData(sql)

            If dt.Rows.Count <> 0 Then
                Response.Redirect("Maintain.aspx")
                Return
            End If
        End If
    End Sub
#End Region

#Region "頁面事件"
    Protected Sub btnLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLogin.Click
        Me.UserID = Me.txtUserID.Text
        Me.CheckMaintain() 'add by angus 20120830 for system maintain
        Me.Login()
    End Sub

    Protected Sub btnReset_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnReset.Click
        Me.txtUserID.Text = ""
        Me.txtPassword.Text = ""
    End Sub

    Protected Sub btnSSOLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSSOLogin.Click
        Dim ssoUrl As String = MyObj.GetParameter("Login", "SSOUrl")

        Response.Redirect(ssoUrl)
    End Sub
#End Region

#Region "屬性"
    Public Property UserID() As String
        Get
            Return ViewState("UserID")
        End Get
        Set(ByVal value As String)
            ViewState("UserID") = value
        End Set
    End Property

#End Region

End Class
